//
// Created by Aleksey Timin on 12/18/19.
//

#include <gtest/gtest.h>

#include <utility>
#include "Mocks.h"
#include "DiscoveryManager.h"

using namespace eipScanner;

class TDiscoveryManager : public DiscoveryManager {
public:
	TDiscoveryManager(sockets::BaseSocket::SPtr  socket)
			: DiscoveryManager("255.255.255.255", 0, std::chrono::milliseconds(0))
			, _mockSocket(std::move(socket)) {

	}

protected:
	sockets::BaseSocket::SPtr makeSocket() const override {
		return _mockSocket;
	}

	sockets::BaseSocket::SPtr _mockSocket;

};
class TestDiscoveryManager: public ::testing::Test {
public:
	const static cip::CipUint OBJECT_ID = 1;
	const std::vector<uint8_t> LIST_IDENTITY_REQUEST = {
			0x63, 0x0, 0x0, 0x0, 0x0, 0x0,
			0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
			0x0, 0x0,
	};

	const std::vector<uint8_t> LIST_IDENTITY_RESPONSE = {
			0xc6, 0x63, 0x0, 0, 0x0, 0x0, 0x0,
			0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
			0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
			0x2, 0x0,
			0xc, 0x0, 0x42, 0x0, 0x1, 0x0, 0x0, 0x2, 0xaf, 0x12, 0xc0, 0xa8,
			0x1, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x96, 0x0, 0x9, 0x0,
			0x5, 0x1, 0x30, 0x0, 0x92, 0xe1, 0x8d, 0x80, 0x1d, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x46, 0x6c,
			0x65, 0x78, 0x20, 0x35, 0x32, 0x35, 0x20, 0x31, 0x50, 0x20, 0x31, 0x31, 0x30, 0x56, 0x20, 0x20,
			0x20, 0x2e, 0x35, 0x30, 0x48, 0x50, 0x0, 0x0, 0x0, 0xff,

			0xc, 0x0, 0x42, 0x0, 0x1, 0x0, 0x0, 0x2, 0xaf, 0x12, 0xc0, 0xa8,
			0x1, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x96, 0x0, 0x9, 0x0,
			0x5, 0x1, 0x30, 0x0, 0x92, 0xe1, 0x8d, 0x80, 0x1d, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x46, 0x6c,
			0x65, 0x78, 0x20, 0x35, 0x32, 0x35, 0x20, 0x31, 0x50, 0x20, 0x31, 0x31, 0x30, 0x56, 0x20, 0x20,
			0x20, 0x2e, 0x35, 0x30, 0x48, 0x50, 0x0, 0x0, 0x0, 0xff,

	};

	void SetUp() override {
		_mockSocket = std::make_shared<TMockSocket>();
	}

	TMockSocket::SPtr _mockSocket;
};

TEST_F(TestDiscoveryManager, ShouldSendBroadcastMessageAndGetResponses) {
	TDiscoveryManager manager(_mockSocket);

	EXPECT_CALL(*_mockSocket, Send(LIST_IDENTITY_REQUEST)).Times(1);
	EXPECT_CALL(*_mockSocket, Receive(504))
		.WillOnce(::testing::Return(LIST_IDENTITY_RESPONSE))
		.WillOnce(::testing::Return(LIST_IDENTITY_RESPONSE))
		.WillOnce(::testing::Throw(std::system_error(DISCOVERY_SOCKET_RECEIVE_END_ERROR_CODE, std::system_category())));

	auto devices = manager.discover();

	EXPECT_EQ(4, devices.size());
	EXPECT_EQ("PowerFlex 525 1P 110V   .50HP", devices[3].identityObject.getProductName());
	EXPECT_EQ(1, devices[1].identityObject.getVendorId());
	EXPECT_EQ("192.168.1.15:44818", devices[0].socketAddress.toString());
}